﻿namespace PLMonitor;

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

/// <inheritdoc />
/// <summary>
/// TCP Client网络通讯适配器 [支持多网卡结构]
/// TCPC:本机IP(可选):目标IP:目标端口号
/// </summary>
public class TcpClientAdapter : CommAdapter
{
    #region 成员变量
    private readonly IPEndPoint _destEp;
    private readonly IPEndPoint _localEp;
    private readonly byte[] _rcvBuf = new byte[4096];
    private Thread? _socketRcvThread;
    private bool _isRunning;    
    private TcpClient? _tcpClient;
    #endregion

    public TcpClientAdapter(string strDesc)
    {
        // 分析字符串并初始化TcpClient连接        
        var strPara = strDesc.Split(':');
        if (strPara.Length != 5)
        {
            throw new Exception($"Invalid TcpClientAdapter Description:{strDesc}");
        }
        var srcPort = Convert.ToInt32(strPara[2]);
        var destPort = Convert.ToInt32(strPara[4]);

        _localEp = new IPEndPoint(IPAddress.Parse(strPara[1]), srcPort);        
        _destEp = new IPEndPoint(IPAddress.Parse(strPara[3]), destPort);
    }

    /// <summary>
    /// 打开通讯适配器
    /// </summary>
    public override bool Open()
    {
        try
        {
            if (_isRunning) return true;
            if (_tcpClient == null)
            {
                _tcpClient = new TcpClient(_localEp);
                _tcpClient.Connect(_destEp);                
            }

            if (_tcpClient.Connected)
            {
                _socketRcvThread = new Thread(SocketReceiveHandle)
                {
                    IsBackground = true
                };
                _socketRcvThread.Start();
                _isRunning = true;
            }
            return true;
        }
        catch(Exception exp)
        {
            _tcpClient?.Dispose();
            NotifyCommError($"Socket Connect Error: {exp}!");
            return false;
        }
    }

    private void SocketReceiveHandle()
    {
        var socket = _tcpClient?.Client;
        while (_isRunning)
        {
            try
            {                
                if (socket == null)
                {
                    _isRunning = false;
                    break;
                }

                if (socket.Poll(100, SelectMode.SelectRead))
                {
                    var ep = (EndPoint)_destEp;
                    var len = socket.ReceiveFrom(_rcvBuf, ref ep);
                    if (len > 0)
                    {
                        NotifyDataRcv(_rcvBuf, len);
                    }
                }

            }
            catch (Exception exp)
            {
                _isRunning = false;//Stop Socket Recv Thread
                NotifyCommError($"Socket Receive Error: {exp}!");
            }
        }

        // 关闭处理
        if (null != socket)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
            socket.Dispose();
        }
    }

    /// <inheritdoc />
    /// <summary>
    /// 关闭适配器
    /// </summary>
    public override void Close()
    {
        _isRunning = false;
        Thread.Sleep(200);
    }

    /// <inheritdoc />
    /// <summary>
    /// 判断端口是否打开
    /// </summary>
    public override bool IsOpened => _isRunning;

    public override void Write(string text)
    {
        if (!_isRunning) return;
        var socket = _tcpClient?.Client;
        var bytes = Encoding.ASCII.GetBytes(text);
        socket?.SendTo(bytes, bytes.Length, SocketFlags.None, _destEp);
    }

    public override void Write(byte[] buffer, int offset, int len)
    {
        if (_isRunning)
        {
            var socket = _tcpClient?.Client;
            socket?.SendTo(buffer, offset, len, SocketFlags.None, _destEp);
        }
    }

    public override void Write(byte[] buffer)
    {
        if (!_isRunning) return;
        var socket = _tcpClient?.Client;
        socket?.SendTo(buffer, 0, buffer.Length, SocketFlags.None, _destEp);
    }
}//end TcpClientAdapter

